// darwin_manager.go
package service

import (
	"fmt"
	"os/exec"
	"strconv"
	"strings"
	"time"
)

// DarwinServiceManager macOS 服务管理器
type DarwinServiceManager struct{}

// NewDarwinServiceManager 创建 macOS 服务管理器
func NewDarwinServiceManager() *DarwinServiceManager {
	return &DarwinServiceManager{}
}

// Status 获取 macOS 服务状态
func (dsm *DarwinServiceManager) Status(serviceName string) (*ServiceInfo, error) {
	// macOS 使用 launchctl 管理服务
	cmd := exec.Command("launchctl", "list", serviceName)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("failed to get service status: %v", err)
	}

	return dsm.parseLaunchCtlOutput(serviceName, string(output)), nil
}

// Start 启动 macOS 服务
func (dsm *DarwinServiceManager) Start(serviceName string) error {
	cmd := exec.Command("launchctl", "start", serviceName)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("failed to start service %s: %v, output: %s", serviceName, err, string(output))
	}
	return nil
}

// Stop 停止 macOS 服务
func (dsm *DarwinServiceManager) Stop(serviceName string) error {
	cmd := exec.Command("launchctl", "stop", serviceName)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("failed to stop service %s: %v, output: %s", serviceName, err, string(output))
	}
	return nil
}

// Restart 重启 macOS 服务
func (dsm *DarwinServiceManager) Restart(serviceName string) error {
	if err := dsm.Stop(serviceName); err != nil {
		return err
	}
	time.Sleep(1 * time.Second)
	return dsm.Start(serviceName)
}

// List 列出所有 macOS 服务
func (dsm *DarwinServiceManager) List() ([]ServiceInfo, error) {
	cmd := exec.Command("launchctl", "list")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("failed to list services: %v", err)
	}

	return dsm.parseLaunchCtlList(string(output)), nil
}

// Logs 获取 macOS 服务日志
func (dsm *DarwinServiceManager) Logs(serviceName string, lines int) (string, error) {
	// macOS 使用 log 命令查看日志
	cmd := exec.Command("log", "show", "--predicate", fmt.Sprintf("subsystem contains '%s'", serviceName),
		"--last", "1h")
	output, err := cmd.CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("failed to get service logs: %v", err)
	}

	return string(output), nil
}

// IsRunning 检查服务是否运行
func (dsm *DarwinServiceManager) IsRunning(serviceName string) (bool, error) {
	status, err := dsm.Status(serviceName)
	if err != nil {
		return false, err
	}
	return status.Status == "running", nil
}

// Enable 启用 macOS 服务
func (dsm *DarwinServiceManager) Enable(serviceName string) error {
	cmd := exec.Command("launchctl", "load", fmt.Sprintf("/Library/LaunchDaemons/%s.plist", serviceName))
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("failed to enable service %s: %v, output: %s", serviceName, err, string(output))
	}
	return nil
}

// Disable 禁用 macOS 服务
func (dsm *DarwinServiceManager) Disable(serviceName string) error {
	cmd := exec.Command("launchctl", "unload", fmt.Sprintf("/Library/LaunchDaemons/%s.plist", serviceName))
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("failed to disable service %s: %v, output: %s", serviceName, err, string(output))
	}
	return nil
}

// parseLaunchCtlOutput 解析 launchctl list 输出
func (dsm *DarwinServiceManager) parseLaunchCtlOutput(serviceName, output string) *ServiceInfo {
	info := &ServiceInfo{Name: serviceName}

	lines := strings.Split(output, "\n")
	if len(lines) > 1 {
		// 第二行包含状态信息
		fields := strings.Fields(lines[1])
		if len(fields) >= 3 {
			pid, _ := strconv.Atoi(fields[0])
			info.PID = pid
			info.Status = dsm.mapDarwinStatus(fields[2])
		}
	}

	return info
}

// parseLaunchCtlList 解析 launchctl list 列表输出
func (dsm *DarwinServiceManager) parseLaunchCtlList(output string) []ServiceInfo {
	var services []ServiceInfo

	lines := strings.Split(output, "\n")
	for i, line := range lines {
		if i == 0 {
			continue // 跳过标题行
		}

		fields := strings.Fields(line)
		if len(fields) >= 3 {
			service := ServiceInfo{
				Name:   fields[2],
				PID:    atoi(fields[0]),
				Status: dsm.mapDarwinStatus(fields[1]),
			}
			services = append(services, service)
		}
	}

	return services
}

// mapDarwinStatus 映射 macOS 服务状态
func (dsm *DarwinServiceManager) mapDarwinStatus(darwinStatus string) string {
	switch darwinStatus {
	case "0":
		return "stopped"
	default:
		return "running"
	}
}

// atoi 安全字符串转整数
func atoi(s string) int {
	val, _ := strconv.Atoi(s)
	return val
}
